package com.ciaojian.core.bytedance;


import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class ByteDanceSignUtil {
    // 签名生成 JAVA示例
    public static String getSignature( String method, String url, Long timestamp,String body) throws Exception {
        String nonce = ByteDanceMiniConfig.NONCE_STR;
        StringBuffer buffer = new StringBuffer();
        buffer.append(method).append("\n");
        buffer.append(url).append("\n");
        buffer.append(timestamp).append("\n");
        buffer.append(nonce).append("\n");
        buffer.append(body).append("\n");
        System.out.println(buffer);
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(string2PrivateKey());
        sign.update(buffer.toString().getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    // string2PrivateKey 仅供参考
    public static PrivateKey string2PrivateKey() {
        PrivateKey prvKey = null;
        try {
            java.security.Security.addProvider(
                    new org.bouncycastle.jce.provider.BouncyCastleProvider()
            );
            byte[] privateBytes = Base64.getDecoder().decode(ByteDanceMiniConfig.PRIVATE_KEY);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            prvKey = keyFactory.generatePrivate(keySpec);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return prvKey;
    }

    public static boolean verify(String httpBody, String signStr, Long timestamp, String nonce) throws Exception {
        StringBuffer buffer = new StringBuffer();
        buffer.append(timestamp).append("\n");
        buffer.append(nonce).append("\n");
        buffer.append(httpBody).append("\n");
        String message = buffer.toString();
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initVerify(string2PublicKey(ByteDanceMiniConfig.PUBLIC_KEY));
        sign.update(message.getBytes(StandardCharsets.UTF_8));
        return sign.verify(Base64.getDecoder().decode(signStr.getBytes(StandardCharsets.UTF_8)));
    }

    // string2PrivateKey 仅供参考
    public static PublicKey string2PublicKey(String publicKey) throws Exception{
        byte[] decoded = Base64.getDecoder().decode(publicKey);
        return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
    }
}
